using System;
using UnityEngine;

public class TPSCamera : MonoBehaviour
{
	[Serializable]
	public enum TPSCameraType
	{
		Top = 0,
		Side = 1,
		TopStreif = 2,
		SideStreif = 3,
		Vehicle = 4
	}

	public static TPSCamera instance;

	private Transform _rocketLeaguePivot;

	private Transform _titanPivot;

	private Transform pivot;

	public LayerMask LayerCast;

	private float currentClosestDistance;

	private float sensitivity = 12f;

	public Camera mainCamera;

	public Camera lodCamera;

	public Transform cameraTarget;

	private PlayerBehavior cameraTargetPlayerBehavior;

	private CarBehavior cameraTargetCarBehavior;

	private HelicopterBehavior cameraTargetHelicopterBehavior;

	private TitanBehavior cameraTargetTitanBehavior;

	private EntityBehavior cameraTargetEntityBehavior;

	public bool streif;

	public float streifOffTimer = 1.5f;

	public float streifOnTimer = 1.5f;

	private float currentStreifOnTimer;

	private float currentStreifOffTimer;

	public bool sniperMode;

	[Range(-2f, 2f)]
	public float rightOffset = 0.75f;

	private float normalRightOffset;

	[Range(-15f, 15f)]
	public float forwardOffset = 5f;

	private float normalForwardOffset;

	[Range(0f, 4f)]
	public float upOffset = 0.4f;

	private float normalUpOffset;

	[Range(0f, 12f)]
	public float maxVelocityOffset = 10f;

	[Range(0f, 12f)]
	public float boostVelocityOffset = 10f;

	[Range(1f, 10f)]
	public float cameraSpeed = 2f;

	public float carCameraSpeedMiltiplyer = 2f;

	public float lowRightOffset = 0.8f;

	private float wantedRightOffset;

	public float lowUpOffset = 0.8f;

	private float wantedUpOffset;

	private float wantedCameraAngel;

	public float currentCameraAmgle;

	[SerializeField]
	private Transform audioListener;

	private TPSCameraType currentCameraType;

	private TPSCameraType wantedCameraType;

	public bool smoothChangeTarget;

	private Vector2 smallMouseDelta = Vector2.zero;

	private Vector2 bigMouseDelta = Vector2.zero;

	private float startPivotAngY;

	private float startPivotAngX;

	public bool isRotating;

	public bool dragCamera;

	public float dragCameraOffTimer = 2f;

	private float curretDragCameraOffTimer;

	public bool roundPass;

	public float roundPassTime = 3f;

	private float currentRoundPassTime;

	private float angX;

	private float angY;

	private Vector2 prevBigMouseDelta;

	public float smoothTime = 0.02f;

	public float maxTopAng = 89.9f;

	public float maxBottompAng = -89.9f;

	private float sensitivityX = 12f;

	private Quaternion tmpPivotRotation;

	public bool clamp = true;

	public bool onLoop;

	public bool rollingOffLoop;

	public float rollingOffLoopTime = 2f;

	private float rollingOffLoopCurrentTime;

	private float targetOrintation;

	private float distanceVel;

	private float closestDistance;

	private Vector3 relVel;

	private float w = 1.6f;

	private float h = 0.6f;

	private Vector3 centerRect;

	private Vector3 leftTop;

	private Vector3 leftBottom;

	private Vector3 rightBottom;

	private Vector3 rightTop;

	private float dist;

	private float nearClip;

	private Vector3 targetPos;

	private float tmpNormalForwardOffset = 0.1f;

	public float maxCloseDistanceConst = 1f;

	private bool obstacle;

	private Vector3 pivotRelCenter;

	private float curShoulderLength;

	private float curUpShoulderLength;

	private Vector3 offsetUp;

	private Vector3 offsetRight;

	private RaycastHit hitinfoPivotPos;

	private float pivotHeight = 1.5f;

	private Vector3 tmpPivotPos;

	private float tankUpOffset = 6f;

	private float tankSniperUpOffset = 6f;

	private Vector3 playerDirection;

	private Vector3 carMovmentDirection = Vector3.zero;

	private float cameraTargetVelocity;

	private Vector3 lastCameraTargePosition;

	private float cameraTargetDirection;

	public bool cameraShake;

	public float defaultShakeAmount = 0.3f;

	private float defaultShakeTime = 1f;

	private float currentShakeAmount;

	private float currentShakeTime;

	private RaycastHit cameraRayHit;

	public Vector3 cameraHitPoint;

	public string cameraHitTag;

	private Vector3 lastCamForward = Vector3.zero;

	public float camAngle;

	public float rayLenght;

	public bool tankSniperMode;

	private Transform rocketLeaguePivot
	{
		get
		{
			if (_rocketLeaguePivot == null)
			{
				_rocketLeaguePivot = new GameObject("Rocket_League_Pivot").transform;
			}
			_rocketLeaguePivot.position = pivot.position;
			return _rocketLeaguePivot;
		}
	}

	public Transform titanPivot
	{
		get
		{
			if (_titanPivot == null)
			{
				_titanPivot = new GameObject("Titan_Pivot").transform;
			}
			_titanPivot.position = pivot.position;
			_titanPivot.rotation = pivot.rotation;
			return _titanPivot;
		}
	}

	public static event Action AfterLateUpdate;

	private void Awake()
	{
		instance = this;
		mainCamera = Camera.main;
		lodCamera = NGUITools.FindCameraForLayer(28);
		currentRoundPassTime = roundPassTime;
		SensitivityChanger.OnSensitivityChanged += UpdateSensitivity;
		UpdateSensitivity();
	}

	private void OnDestroy()
	{
		SensitivityChanger.OnSensitivityChanged -= UpdateSensitivity;
	}

	public void UpdateSensitivity()
	{
		float num = BCWStorage.Get<float>(settings.keySensivity);
		sensitivity = ((!(num > 0f)) ? 12f : num);
		sensitivityX = sensitivity;
	}

	public void SetCameraTarget(Transform target, bool smoothChange = false)
	{
		tankSniperMode = false;
		smoothChangeTarget = smoothChange;
		if (CameraModeControl.instance.mainCameraType != settings.MainCameraType.FPSCamera)
		{
			base.enabled = true;
		}
		if (!(cameraTarget != target))
		{
			return;
		}
		cameraTarget = target;
		if ((bool)target.GetComponent<EntityBehavior>())
		{
			cameraTargetEntityBehavior = target.GetComponent<EntityBehavior>();
			forwardOffset = cameraTargetEntityBehavior.cameraOffset;
			wantedCameraAngel = cameraTargetEntityBehavior.cameraAngle;
			currentCameraAmgle = wantedCameraAngel;
		}
		else
		{
			cameraTargetEntityBehavior = null;
		}
		if ((bool)target.GetComponent<PlayerBehavior>())
		{
			cameraTargetPlayerBehavior = target.GetComponent<PlayerBehavior>();
			wantedCameraAngel = cameraTargetPlayerBehavior.cameraAngle;
			currentCameraAmgle = wantedCameraAngel;
		}
		else
		{
			cameraTargetPlayerBehavior = null;
		}
		if ((bool)target.GetComponent<CarBehavior>())
		{
			cameraTargetCarBehavior = target.GetComponent<CarBehavior>();
			if (cameraTargetCarBehavior.cameraP != null)
			{
				cameraTarget = cameraTargetCarBehavior.cameraP;
			}
		}
		else
		{
			cameraTargetCarBehavior = null;
		}
		if ((bool)target.GetComponent<TitanBehavior>())
		{
			cameraTargetTitanBehavior = target.GetComponent<TitanBehavior>();
			forwardOffset = cameraTargetTitanBehavior.cameraOffset;
			wantedCameraAngel = cameraTargetTitanBehavior.cameraAngle;
			currentCameraAmgle = wantedCameraAngel;
		}
		else
		{
			cameraTargetTitanBehavior = null;
		}
		if ((bool)target.GetComponent<HelicopterBehavior>())
		{
			cameraTargetHelicopterBehavior = target.GetComponent<HelicopterBehavior>();
		}
		else
		{
			cameraTargetHelicopterBehavior = null;
		}
	}

	public void SetCamera(TPSCameraType cameraType, Transform target = null, bool smoothTargetChange = false, bool resetRosition = false, bool permanent = false)
	{
		if (target != null)
		{
			SetCameraTarget(target, smoothTargetChange);
		}
		else
		{
			SetCameraTarget(GameController.instance.playerScript.transform, smoothTargetChange);
		}
		InstantiatePivots();
		if (resetRosition)
		{
			DisableTankSniperMode();
			ResetPivotPos();
		}
		switch (cameraType)
		{
		case TPSCameraType.Top:
			rightOffset = 0.4f;
			forwardOffset = 6f;
			upOffset = 1.1f;
			maxBottompAng = -89.9f;
			maxTopAng = 89.9f;
			wantedRightOffset = rightOffset;
			wantedUpOffset = upOffset;
			streif = false;
			if (currentCameraType == TPSCameraType.Vehicle)
			{
				roundPass = true;
				currentRoundPassTime = roundPassTime;
			}
			sniperMode = false;
			sensitivityX = sensitivity * 1f;
			break;
		case TPSCameraType.TopStreif:
			rightOffset = 0.4f;
			forwardOffset = 3f;
			upOffset = 1.1f;
			maxBottompAng = -89.9f;
			maxTopAng = 89.9f;
			wantedRightOffset = rightOffset;
			wantedUpOffset = upOffset;
			roundPass = false;
			break;
		case TPSCameraType.Side:
			rightOffset = 1.2f;
			forwardOffset = 4.5f;
			upOffset = 0.7f;
			maxBottompAng = -89.9f;
			maxTopAng = 89.9f;
			wantedRightOffset = rightOffset;
			wantedUpOffset = upOffset;
			streif = false;
			if (currentCameraType == TPSCameraType.Vehicle)
			{
				roundPass = true;
				currentRoundPassTime = roundPassTime;
			}
			sniperMode = false;
			sensitivityX = sensitivity * 1f;
			break;
		case TPSCameraType.SideStreif:
			rightOffset = 1.2f;
			forwardOffset = 2.5f;
			upOffset = 0.7f;
			maxBottompAng = -89.9f;
			maxTopAng = 89.9f;
			wantedRightOffset = rightOffset;
			wantedUpOffset = upOffset;
			roundPass = false;
			break;
		case TPSCameraType.Vehicle:
			DisableTankSniperMode();
			rightOffset = 0f;
			upOffset = 0f;
			maxBottompAng = -1f;
			if ((bool)cameraTargetCarBehavior && cameraTargetCarBehavior.carWithWeapon && cameraTargetCarBehavior.RCCcar.vehicleType != VehicleType.Boat)
			{
				maxBottompAng = -30f;
				maxTopAng = 30f;
			}
			streif = false;
			roundPass = true;
			currentRoundPassTime = roundPassTime;
			sniperMode = false;
			sensitivityX = sensitivity * 1f;
			break;
		}
		if (permanent)
		{
			wantedCameraType = cameraType;
		}
		currentCameraType = cameraType;
		currentClosestDistance = normalForwardOffset;
	}

	private void InstantiatePivots()
	{
		if (pivot == null)
		{
			pivot = new GameObject().transform;
			pivot.name = "TPS_Camera_Pivot";
			pivot.position = cameraTarget.position;
			base.transform.SetParent(pivot);
			base.transform.localPosition = Vector3.zero;
		}
	}

	public void SetStreifCamera()
	{
		if ((bool)cameraTargetTitanBehavior)
		{
			streif = false;
		}
		else if (!streif)
		{
			streif = true;
			if ((bool)cameraTargetPlayerBehavior)
			{
				cameraTargetPlayerBehavior.mecanimWrapper.RefreshTransitionState();
			}
			currentStreifOffTimer = streifOffTimer;
			currentStreifOnTimer = 0f;
			switch (wantedCameraType)
			{
			case TPSCameraType.Top:
				SetCamera(TPSCameraType.TopStreif);
				break;
			case TPSCameraType.Side:
				SetCamera(TPSCameraType.SideStreif);
				break;
			}
		}
	}

	public void SetNormalCamera()
	{
		if (streif)
		{
			streif = false;
			currentStreifOffTimer = 0f;
			currentStreifOnTimer = streifOnTimer;
			SetCamera(wantedCameraType);
		}
	}

	public void SetMouseDelta(Vector2 delta)
	{
		smallMouseDelta = delta;
	}

	public void OnEnterSniperMode()
	{
		sensitivityX = sensitivity * 0.2f;
		sniperMode = true;
	}

	public void OnExitSniperMode()
	{
		sensitivityX = sensitivity * 1f;
		sniperMode = false;
	}

	public void OnStartRotation()
	{
		if (pivot != null)
		{
			isRotating = true;
			dragCamera = true;
			roundPass = false;
			startPivotAngY = pivot.localEulerAngles.y;
			startPivotAngX = pivot.localEulerAngles.x;
			if (pivot.forward.y > 0f)
			{
				startPivotAngX -= 360f;
			}
			prevBigMouseDelta = Vector2.zero;
			bigMouseDelta = Vector2.zero;
		}
	}

	public void OnEndRotation()
	{
		if (pivot != null)
		{
			isRotating = false;
			curretDragCameraOffTimer = dragCameraOffTimer;
		}
	}

	public static float SignedAngle(Vector3 a, Vector3 b, Vector3 normal)
	{
		Vector3 lhs = Vector3.Cross(normal, a);
		float num = Vector3.Angle(a, b);
		return num * Mathf.Sign(Vector3.Dot(lhs, b));
	}

	private void CameraDragAndResetPos()
	{
		if (dragCamera)
		{
			prevBigMouseDelta = bigMouseDelta;
			angX = prevBigMouseDelta.x * sensitivityX * 30f / (float)Screen.width;
			angY = (0f - prevBigMouseDelta.y) * sensitivityX * 30f / (float)Screen.width;
			float num = angY + startPivotAngX;
			if (num <= -180f)
			{
				num += 360f;
			}
			else if (num > 180f)
			{
				num -= 360f;
			}
			num = Mathf.Clamp(num, maxBottompAng, maxTopAng);
			pivot.localEulerAngles = new Vector3(num, startPivotAngY + angX, 0f);
		}
		else
		{
			tmpPivotRotation = cameraTarget.rotation;
			if (!roundPass)
			{
				if ((bool)cameraTargetPlayerBehavior)
				{
					if (!sniperMode && !streif && cameraTargetPlayerBehavior.isGrounded && cameraTargetVelocity > 0.01f)
					{
						if (cameraTargetDirection > -0.85f)
						{
							tmpPivotRotation.eulerAngles = new Vector3(tmpPivotRotation.eulerAngles.x + currentCameraAmgle, tmpPivotRotation.eulerAngles.y, 0f);
						}
						else
						{
							tmpPivotRotation.eulerAngles = new Vector3(tmpPivotRotation.eulerAngles.x + currentCameraAmgle, tmpPivotRotation.eulerAngles.y + 180f, 0f);
						}
						pivot.rotation = Quaternion.Lerp(pivot.rotation, tmpPivotRotation, Time.deltaTime * cameraSpeed * 0.4f);
					}
				}
				else if (cameraTargetVelocity > 0.03f && GameController.instance.curTypeGame != TypeGame.RocketLeague)
				{
					bool flag = false;
					if ((bool)cameraTargetCarBehavior)
					{
						if (cameraTargetCarBehavior.carWithWeapon && cameraTargetCarBehavior.RCCcar.vehicleType != VehicleType.Boat)
						{
							return;
						}
						flag = cameraTargetCarBehavior.isFlaing;
						float num2 = 45f;
						if (Vector3.Angle(cameraTarget.forward, Vector3.up) < num2 || Vector3.Angle(cameraTarget.right, Vector3.up) < num2 || Vector3.Angle(-cameraTarget.right, Vector3.up) < num2)
						{
							flag = true;
						}
					}
					float num3 = SignedAngle(carMovmentDirection, cameraTarget.forward, Vector3.up);
					if ((bool)cameraTargetHelicopterBehavior || Mathf.Abs(num3) < 1.5f)
					{
						num3 = 0f;
					}
					if (!flag)
					{
						float num4 = carCameraSpeedMiltiplyer * cameraTargetVelocity;
						if (cameraTargetDirection >= 0f)
						{
							tmpPivotRotation.eulerAngles = new Vector3(tmpPivotRotation.eulerAngles.x + currentCameraAmgle, tmpPivotRotation.eulerAngles.y - num3, tmpPivotRotation.eulerAngles.z);
						}
						else
						{
							tmpPivotRotation.eulerAngles = new Vector3(360f - tmpPivotRotation.eulerAngles.x + currentCameraAmgle, tmpPivotRotation.eulerAngles.y + num3, tmpPivotRotation.eulerAngles.z);
						}
						pivot.rotation = Quaternion.Lerp(pivot.rotation, tmpPivotRotation, Time.deltaTime * cameraSpeed * carCameraSpeedMiltiplyer * cameraTargetVelocity);
					}
					else
					{
						onLoop = false;
						tmpPivotRotation = pivot.rotation;
						tmpPivotRotation.eulerAngles = new Vector3(30f, tmpPivotRotation.eulerAngles.y, tmpPivotRotation.eulerAngles.z);
						pivot.rotation = Quaternion.Lerp(pivot.rotation, tmpPivotRotation, Time.deltaTime * cameraSpeed);
					}
				}
			}
			else
			{
				tmpPivotRotation.eulerAngles = new Vector3(tmpPivotRotation.eulerAngles.x + currentCameraAmgle, tmpPivotRotation.eulerAngles.y, tmpPivotRotation.eulerAngles.z);
				pivot.rotation = Quaternion.Lerp(pivot.rotation, tmpPivotRotation, Time.deltaTime * cameraSpeed);
			}
		}
		if (cameraTargetCarBehavior != null && cameraTargetCarBehavior.onBoost)
		{
			normalForwardOffset = Mathf.Lerp(normalForwardOffset, forwardOffset + boostVelocityOffset * cameraTargetVelocity, Time.deltaTime * cameraSpeed * 100f);
		}
		else
		{
			normalForwardOffset = Mathf.Lerp(normalForwardOffset, forwardOffset + maxVelocityOffset * cameraTargetVelocity, Time.deltaTime * cameraSpeed * 100f);
		}
		normalRightOffset = Mathf.Lerp(normalRightOffset, rightOffset, Time.deltaTime * cameraSpeed);
		normalUpOffset = Mathf.Lerp(normalUpOffset, upOffset, Time.deltaTime * cameraSpeed);
		if (!dragCamera && !roundPass && GameController.instance.curTypeGame == TypeGame.RocketLeague)
		{
			rocketLeaguePivot.LookAt(RocketLeagueCotroller.instance.rocketLeagueBall.transform);
			float num5 = rocketLeaguePivot.eulerAngles.x + 20f;
			float y = rocketLeaguePivot.eulerAngles.y;
			if (num5 <= -180f)
			{
				num5 += 360f;
			}
			else if (num5 > 180f)
			{
				num5 -= 360f;
			}
			num5 = Mathf.Clamp(num5, maxBottompAng, maxTopAng);
			pivot.rotation = Quaternion.Slerp(pivot.rotation, Quaternion.Euler(num5, y, 0f), Time.deltaTime * cameraSpeed);
			return;
		}
		if (!isRotating && dragCamera)
		{
			if (curretDragCameraOffTimer > 0f)
			{
				curretDragCameraOffTimer -= Time.deltaTime;
			}
			else
			{
				dragCamera = false;
			}
		}
		if (roundPass)
		{
			if (currentRoundPassTime > 0f)
			{
				currentRoundPassTime -= Time.deltaTime;
			}
			else
			{
				roundPass = false;
				currentRoundPassTime = roundPassTime;
			}
			if (cameraTargetVelocity > 1f)
			{
				roundPass = false;
				currentRoundPassTime = roundPassTime;
			}
		}
	}

	private void ManageUpperAndLowerCameraPos()
	{
		bigMouseDelta.x += smallMouseDelta.x;
		if (pivot.forward.y <= 0f)
		{
			if (!(pivot.localEulerAngles.x >= maxTopAng) || !(smallMouseDelta.y < 0f))
			{
				bigMouseDelta.y += smallMouseDelta.y;
			}
			return;
		}
		if (!(pivot.localEulerAngles.x <= 360f + maxBottompAng) || !(smallMouseDelta.y > 0f))
		{
			bigMouseDelta.y += smallMouseDelta.y;
		}
		if (currentCameraType == TPSCameraType.Top || currentCameraType == TPSCameraType.TopStreif)
		{
			if (360f - pivot.localEulerAngles.x > 20f)
			{
				rightOffset = lowRightOffset;
				upOffset = lowUpOffset;
			}
			else
			{
				rightOffset = wantedRightOffset;
				upOffset = wantedUpOffset;
			}
		}
	}

	private void ManageStreif()
	{
		if ((bool)cameraTargetTitanBehavior)
		{
			streif = false;
		}
		else
		{
			if (!cameraTargetPlayerBehavior)
			{
				return;
			}
			if (isRotating && cameraTargetPlayerBehavior.isGrounded)
			{
				currentStreifOffTimer = streifOffTimer;
				currentStreifOnTimer -= Time.deltaTime;
				if (currentStreifOnTimer <= 0f)
				{
					SetStreifCamera();
				}
			}
			else
			{
				currentStreifOnTimer = streifOnTimer;
				currentStreifOffTimer -= Time.deltaTime;
				if (currentStreifOffTimer <= 0f)
				{
					SetNormalCamera();
				}
			}
		}
	}

	private void ManageCameraPos()
	{
		targetOrintation = Vector3.Dot(Vector3.up, cameraTarget.up);
		if (onLoop || rollingOffLoop)
		{
			if (targetOrintation <= 0f)
			{
				currentCameraAmgle = 0f - wantedCameraAngel;
			}
			else if (targetOrintation > 0f)
			{
				currentCameraAmgle = wantedCameraAngel;
			}
		}
		if (onLoop)
		{
			if (targetOrintation >= 0.8f)
			{
				onLoop = false;
				rollingOffLoop = true;
				rollingOffLoopCurrentTime = rollingOffLoopTime;
			}
		}
		else if (!rollingOffLoop)
		{
			SetCameraPos();
			base.transform.LookAt(pivot);
		}
		else
		{
			base.transform.rotation = Quaternion.Lerp(base.transform.rotation, Quaternion.LookRotation(pivot.forward, Vector3.up), Time.deltaTime * cameraSpeed);
			if (rollingOffLoopCurrentTime > 0f)
			{
				rollingOffLoopCurrentTime -= Time.deltaTime;
				return;
			}
			rollingOffLoop = false;
			rollingOffLoopCurrentTime = rollingOffLoopTime;
		}
	}

	private void SetCameraPos()
	{
		tmpNormalForwardOffset = normalForwardOffset;
		if (tankSniperMode)
		{
			tmpNormalForwardOffset = 0.1f;
		}
		centerRect = pivot.position - pivot.forward * tmpNormalForwardOffset;
		leftTop = centerRect - base.transform.right * w + base.transform.up * h;
		leftBottom = centerRect - base.transform.right * w - base.transform.up * h;
		rightBottom = centerRect + base.transform.right * w - base.transform.up * h;
		rightTop = centerRect + base.transform.right * w + base.transform.up * h;
		currentClosestDistance = tmpNormalForwardOffset;
		LinecastAll(leftTop);
		LinecastAll(rightTop);
		LinecastAll(leftBottom);
		LinecastAll(rightBottom);
		closestDistance = currentClosestDistance;
		targetPos = pivot.position - pivot.forward * closestDistance;
		if (obstacle || tankSniperMode)
		{
			base.transform.position = targetPos;
		}
		else
		{
			base.transform.position = Vector3.Lerp(base.transform.position, targetPos, Time.deltaTime * cameraSpeed);
		}
	}

	private void LinecastAll(Vector3 target)
	{
		RaycastHit[] array = Physics.RaycastAll(pivot.position, target - pivot.position, tmpNormalForwardOffset, LayerCast);
		RaycastHit[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			RaycastHit raycastHit = array2[i];
			if (raycastHit.collider.tag != "MyVehicle" && !raycastHit.collider.isTrigger)
			{
				dist = Vector3.Project(raycastHit.point - pivot.position, base.transform.position - pivot.position).magnitude;
				if (dist < currentClosestDistance)
				{
					currentClosestDistance = dist;
					obstacle = true;
				}
			}
		}
	}

	private void ResetPivotPos()
	{
		pivot.position = cameraTarget.position + cameraTarget.up * pivotHeight;
		pivot.rotation = cameraTarget.rotation;
		base.transform.localPosition = Vector3.zero;
		base.transform.localRotation = Quaternion.identity;
		base.transform.localPosition = new Vector3(0f, 0.6f, -3.5f);
		cameraShake = false;
	}

	private void SetPivotPos()
	{
		pivotHeight = 1.5f;
		if ((bool)cameraTargetCarBehavior && cameraTargetCarBehavior.carWithWeapon && cameraTargetCarBehavior.RCCcar.vehicleType != VehicleType.Boat)
		{
			if (tankSniperMode)
			{
				pivotHeight = tankSniperUpOffset;
			}
			else
			{
				pivotHeight = tankUpOffset;
			}
		}
		if ((bool)cameraTargetTitanBehavior)
		{
			pivotHeight = cameraTargetTitanBehavior.cameraUpOffset;
		}
		if ((bool)cameraTargetTitanBehavior)
		{
			maxBottompAng = cameraTargetTitanBehavior.cameraAngle;
			maxTopAng = cameraTargetTitanBehavior.cameraAngle;
			rightOffset = 0f;
		}
		if (onLoop)
		{
			tmpPivotPos = cameraTarget.position + cameraTarget.up * pivotHeight;
		}
		else
		{
			tmpPivotPos = cameraTarget.position + Vector3.up * pivotHeight;
		}
		if (smoothChangeTarget)
		{
			if (Vector3.Distance(pivotRelCenter, tmpPivotPos) > 0.015f)
			{
				pivotRelCenter = Vector3.Lerp(pivotRelCenter, tmpPivotPos, Time.deltaTime * cameraSpeed * 4f);
				if (cameraTargetVelocity > 0.09f)
				{
					smoothChangeTarget = false;
				}
			}
			else
			{
				smoothChangeTarget = false;
			}
		}
		else
		{
			pivotRelCenter = tmpPivotPos;
		}
		float b = normalRightOffset;
		Vector3 direction = pivot.right * normalRightOffset + pivot.up * normalUpOffset;
		if (Physics.Raycast(pivotRelCenter, direction, out hitinfoPivotPos, normalRightOffset + 0.375f, LayerCast) && !hitinfoPivotPos.collider.CompareTag("ShootHead") && !hitinfoPivotPos.collider.CompareTag("MyVehicle"))
		{
			b = (hitinfoPivotPos.point - pivotRelCenter).magnitude * 0.75f;
			obstacle = true;
		}
		if (obstacle)
		{
			curShoulderLength = b;
		}
		else
		{
			curShoulderLength = Mathf.Lerp(curShoulderLength, b, Time.deltaTime * cameraSpeed);
		}
		pivot.position = pivotRelCenter + direction.normalized * curShoulderLength;
	}

	private void SetPlayerDirection()
	{
		if ((bool)cameraTargetPlayerBehavior)
		{
			if (streif || cameraTargetPlayerBehavior.tController.jetpack.isFlying)
			{
				playerDirection = Vector3.Lerp(playerDirection, base.transform.position + base.transform.forward * 100f, Time.deltaTime * 5f);
			}
			else if (cameraTargetPlayerBehavior.isGrounded)
			{
				playerDirection = Vector3.Lerp(playerDirection, cameraTarget.position + GameController.instance.playerScript.tController.moveDirection * 100f, Time.deltaTime * 5f);
			}
			if (!cameraTargetPlayerBehavior.onLadder)
			{
				GameController.instance.playerScript.tController.SetTargetPoint(playerDirection);
			}
		}
	}

	private void GetCameraTargetVelicity()
	{
		if ((bool)cameraTargetPlayerBehavior)
		{
			cameraTargetVelocity = cameraTargetPlayerBehavior.tController.moveSpeed;
			cameraTargetDirection = Vector3.Dot(cameraTarget.forward, base.transform.forward);
			if (cameraTargetVelocity > 10f)
			{
				cameraTargetVelocity = 10f;
			}
		}
		if ((bool)cameraTargetCarBehavior)
		{
			cameraTargetVelocity = cameraTargetCarBehavior.GetCurrentSpeed();
			cameraTargetDirection = cameraTargetCarBehavior.GetCurrentDirection();
			Vector3 vector = cameraTarget.position - lastCameraTargePosition;
			if (!vector.Equals(Vector3.zero))
			{
				carMovmentDirection = vector;
			}
		}
		if ((bool)cameraTargetHelicopterBehavior)
		{
			cameraTargetVelocity = cameraTargetHelicopterBehavior.GetCurrentSpeed();
			cameraTargetDirection = Vector3.Dot(cameraTarget.forward, base.transform.forward);
			Vector3 vector2 = cameraTarget.position - lastCameraTargePosition;
			if (!vector2.Equals(Vector3.zero))
			{
				carMovmentDirection = vector2;
			}
		}
		lastCameraTargePosition = cameraTarget.transform.position;
		cameraTargetVelocity = Mathf.Clamp(cameraTargetVelocity, 0f, 65f) / 65f;
		if (cameraTargetVelocity <= 0f)
		{
			cameraTargetVelocity = 1E-09f;
		}
	}

	public void ShakeCameraExplosion(Transform explosionTransform, float maxDistance)
	{
		if ((bool)cameraTarget)
		{
			float num = Vector3.Distance(explosionTransform.position, cameraTarget.position);
			if (num < maxDistance)
			{
				ShakeCamera((1f - num / maxDistance) / 4f, defaultShakeTime);
			}
		}
	}

	public void ShakeCamera()
	{
		ShakeCamera(defaultShakeAmount, defaultShakeTime);
	}

	public void ShakeCamera(float shakeAmoun, float shakeTime)
	{
		cameraShake = true;
		currentShakeAmount = shakeAmoun;
		currentShakeTime = shakeTime;
	}

	private void ApplieCameraShake()
	{
		if (!cameraShake || tankSniperMode)
		{
			return;
		}
		if (currentShakeTime > 0f)
		{
			currentShakeTime -= Time.deltaTime;
			if (currentShakeAmount - Time.deltaTime / 3f > 0f)
			{
				currentShakeAmount -= Time.deltaTime / 3f;
			}
			base.transform.localPosition += UnityEngine.Random.insideUnitSphere * currentShakeAmount;
		}
		else
		{
			currentShakeAmount = defaultShakeAmount;
			currentShakeTime = defaultShakeTime;
			cameraShake = false;
		}
	}

	private void Update()
	{
	}

	private void LateUpdate()
	{
		if (cameraTarget != null && pivot != null)
		{
			ManageUpperAndLowerCameraPos();
			SetPlayerDirection();
			GetCameraTargetVelicity();
			CameraDragAndResetPos();
			SetPivotPos();
			ManageCameraPos();
			ManageStreif();
			ApplieCameraShake();
			obstacle = false;
			PlayerBehavior myPlayer = PlayerBehavior.MyPlayer;
			if (myPlayer != null)
			{
				audioListener.position = myPlayer.transform.position + Vector3.up * 2.25f;
			}
		}
		if (Physics.Raycast(pivot.position, pivot.forward, out cameraRayHit, 100f, LayerCast))
		{
			cameraHitPoint = cameraRayHit.point;
			cameraHitTag = cameraRayHit.collider.tag;
		}
		else
		{
			cameraHitPoint = pivot.position + pivot.forward * 100f;
		}
		rayLenght = Vector3.Distance(pivot.position, cameraHitPoint);
		if (TPSCamera.AfterLateUpdate != null)
		{
			TPSCamera.AfterLateUpdate();
		}
	}

	public void ToggleTankSniperMode()
	{
		if (tankSniperMode)
		{
			DisableTankSniperMode();
		}
		else
		{
			EnableTankSniperMode();
		}
	}

	private void EnableTankSniperMode()
	{
		CarWindow.instance.tankSniperMode.SetActive(true);
		float fieldOfView = 30f;
		if ((bool)cameraTargetCarBehavior)
		{
			cameraTargetCarBehavior.ToggleRenderers(false);
			fieldOfView = cameraTargetCarBehavior.sniperModZoom;
		}
		tankSniperMode = true;
		mainCamera.fieldOfView = fieldOfView;
		if ((bool)lodCamera)
		{
			lodCamera.fieldOfView = fieldOfView;
		}
		OnEnterSniperMode();
	}

	private void DisableTankSniperMode()
	{
		CarWindow.instance.tankSniperMode.SetActive(false);
		if ((bool)cameraTargetCarBehavior)
		{
			cameraTargetCarBehavior.ToggleRenderers(true);
		}
		tankSniperMode = false;
		mainCamera.fieldOfView = 60f;
		if ((bool)lodCamera)
		{
			lodCamera.fieldOfView = 60f;
		}
		OnExitSniperMode();
	}

	public void HideTankSniperMode()
	{
		CarWindow.instance.tankSniperMode.SetActive(false);
		tankSniperMode = false;
		mainCamera.fieldOfView = 60f;
		if ((bool)lodCamera)
		{
			lodCamera.fieldOfView = 60f;
		}
	}
}
